home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / qlib205.zip / QLIB.ZIP / SRC / QLIB / PACK.ASM < prev    next >
Assembly Source File  |  1997-03-20  |  11KB  |  594 lines

  1. ;this is part of file i/o
  2. ;for packed file loading/etc.
  3.  
  4. .data?
  5.  
  6. align 4
  7. pts dd ?  ;table size
  8. phs dd ?  ;handles size
  9.  
  10. old_int21h df ? ;old int21h handler
  11. coff dd ?  ;current file offset (within the pack file)
  12. csiz dd ?  ;current file size
  13. cpos dd ?  ;current file position (0=starting pos)
  14. cend dd ?  ;coff + csiz
  15.  
  16. fn db 13 dup (?)    ;File name used by _open
  17.  
  18. ps struct
  19.   fn db 13 dup (?)   ;the name
  20.   fh dw ?            ;the handle (not used in the header when in the file)
  21.   off dd ?           ;offset in the file
  22.   siz dd ?           ;size of file
  23. ps ends
  24.  
  25. .data
  26. pt dd 0   ;the tables  (malloc'ed)
  27.   ;this holds the struct of each file loaded (within the pack files)
  28. ph dd 0   ;Packs Handles (malloc'ed) FIX : v2.01 : No longer restricted to 16
  29.   ;this holds the handles of each pack file loaded to quickly know when
  30.   ; file IO is being performed on a pack file
  31.  
  32. pack_on db 0  ;is packed file init?
  33. chand dw 0  ;current handle (0=none!)  (if one file is opened then
  34.             ; another cannot be opened!)
  35. temp4 dd 0   ;used all over
  36. noff dd 0    ;# of files (this must come right after temp4)
  37.  
  38. .code
  39.  
  40. readpack proc private,h:word,buf:dword,len:dword
  41.   mov ah,3fh
  42.   mov bx,h
  43.   mov ecx,len
  44.   mov edx,buf
  45.   pushfd
  46.   call [old_int21h]
  47.   ret
  48. readpack endp
  49.  
  50. closepack proc private,h:word
  51.   mov bx,h
  52.   mov ah,3eh
  53.   pushfd
  54.   call [old_int21h]
  55.   ret
  56. closepack endp
  57.  
  58. openpack proc private,nam:dword,acc:byte
  59.   mov edx,nam
  60.   mov ah,3dh
  61.   mov al,acc
  62.   pushfd
  63.   call [old_int21h]
  64.   ret
  65. openpack endp
  66.  
  67. pack_init proc,siz:word,packs:word
  68.   ;siz=# of entries(files)alloced for
  69.   ;packs=# of pack files that can be opened
  70.  
  71.   pushad  ;FIX : v2.01
  72.  
  73.   .if pack_on  ;already installed?
  74.     jmp bad
  75.   .endif
  76.   xor eax,eax
  77.   mov ax,siz
  78.   mov pts,eax
  79.   mov ebx,sizeof ps
  80.   mul ebx
  81.   mov ecx,eax
  82.   invoke malloc,eax
  83.   cmp eax,NULL
  84.   jnz @f
  85. bad:
  86.   .if pt
  87.     callp free,pt
  88.     mov pt,0
  89.   .endif
  90.   .if ph
  91.     callp free,ph
  92.     mov ph,0
  93.   .endif
  94.   popad
  95.   mov errno,ENOMEM
  96.   mov eax,ERROR
  97.   ret
  98. @@:
  99.   mov pt,eax
  100.   mov edi,eax
  101.   xor al,al
  102.   rep stosb  ;clear table
  103.   xor eax,eax
  104.   mov ax,packs
  105.   mov phs,eax
  106.   shl eax,1
  107.   mov ecx,eax
  108.   callp malloc,eax
  109.   cmp eax,NULL
  110.   jz bad
  111.   mov ph,eax
  112.   mov edi,eax
  113.   xor al,al
  114.   rep stosb  ;clear table
  115.   mov pack_on,1
  116.  
  117.   callp getint,21h
  118.   mov word ptr[old_int21h+4],ax
  119.   mov dword ptr[old_int21h],edx
  120.   mov ax,selcode
  121.   mov edx,offset int_21h
  122.   callp setint,21h,ax,edx
  123.   popad
  124.   xor eax,eax  ;FIX : v2.01
  125.   ret
  126. pack_init endp
  127.  
  128. ;it is not necessary to call this during exit()
  129. pack_uninit proc uses esi ecx
  130.   .if !pack_on
  131.     mov eax,ERROR
  132.     ret
  133.   .endif
  134.  
  135. ;restore oringinal DOS INT 21h handler
  136.   mov ax,word ptr[old_int21h+4]
  137.   mov edx,dword ptr[old_int21h]
  138.   callp setint,21h,ax,edx
  139.  
  140. ;close all files used
  141.   mov esi,ph
  142.   mov ecx,phs
  143. @@:
  144.   cmp wptr[esi],0
  145.   .if !zero?
  146.     callp close,wptr[edi]
  147.   .endif
  148.   add esi,2
  149.   dec ecx
  150.   jnz @b
  151.  
  152. ;free buffers
  153.   callp free,pt
  154.   mov pt,0
  155.   callp free,ph
  156.   mov ph,0
  157.  
  158.   mov pack_on,0
  159.   xor eax,eax
  160.   ret
  161. pack_uninit endp
  162.  
  163. open_pack proc private,hdr:dword,h:word
  164.   mov esi,hdr
  165.   mov ebx,noff
  166.   mov edi,pt
  167.   mov edx,pts
  168.   mov ax,h
  169. @@:
  170.   cmp bptr[edi],0
  171.   jz add1file
  172.   add edi,sizeof ps
  173.   dec edx
  174.   jnz @b
  175.   mov eax,ERROR   ;not enough room to load all files
  176.   ret
  177. add1file:
  178.   mov [esi].ps.fh,ax
  179.   mov ecx,sizeof ps
  180.   rep movsb
  181.   dec edx
  182.   dec ebx
  183.   jnz @b
  184.   xor eax,eax ;all loaded it
  185.   ret
  186. open_pack endp
  187.  
  188. pack_open proc,strg:dword  ;opens a packed file
  189.   local h:word,buf:dword
  190.  
  191.   pushad  ;FIX : v2.01
  192. ;look for an empty location in ph
  193.   mov ecx,phs
  194.   xor eax,eax
  195.   mov edi,ph
  196.   repnz scasw
  197.   .if !zero?
  198.     ;non-found
  199.     jmp bad
  200.   .endif
  201.   ;found one!
  202.   sub edi,2  ;edi=>open location
  203.   callp openpack,strg,0  ;for reading only! (objections?)
  204.   cmp eax,ERROR
  205.   jnz @f
  206. bad:
  207.   popad
  208.   mov eax,ERROR
  209.   ret
  210. @@:
  211.   stosw   ;save handle
  212.   mov h,ax
  213. ;now to read in the files  (can't use READ cause it will screw it up)
  214.   callp readpack,ax,offset temp4,6
  215.   .if eax!=6
  216.     callp closepack,h
  217.     jmp bad
  218.   .endif
  219.   mov ebx,offset temp4
  220.   cmp dword ptr[ebx],01a4b4150h ;'PAK',26
  221.   .if !zero?
  222.     callp closepack,h
  223.     jmp bad
  224.   .endif
  225.   xor eax,eax
  226.   mov eax,noff
  227.   mov ebx,sizeof ps
  228.   mul ebx 
  229.   mov ecx,eax  ;siz (save for l8r)
  230.   callp malloc,eax  ;a temp buffer needed to quickly load all structs
  231.   .if eax==ERROR
  232.     callp closepack,h
  233.     jmp bad
  234.   .endif
  235.   mov buf,eax
  236.   callp readpack,h,buf,ecx
  237.  
  238.   callp open_pack,buf,h
  239.   mov ebx,eax  ;save eax...
  240.   callp free,buf  ;release temp buffer
  241.   .if ebx      ;...for here
  242.     callp closepack,h
  243.     popad
  244.     mov eax,ERROR
  245.     ret
  246.   .endif
  247.   popad
  248.   xor eax,eax
  249.   mov ax,h
  250.   ret
  251. pack_open endp
  252.  
  253. ;ADDED : v2.01
  254.   ;opens a packed file (with header already loaded)
  255.   ;these pack files must have been created with the -h option with PACKIT.EXE
  256. pack_open_hdr proc,strg:dword,hdr:dword
  257.   local h:word
  258.  
  259.   pushad
  260.  
  261. ;look for an empty location in ph
  262.   mov ecx,phs
  263.   xor eax,eax
  264.   mov edi,ph
  265.   repnz scasw
  266.   .if !zero?
  267.     ;non-found
  268.     jmp bad
  269.   .endif
  270.   ;found one!
  271.   sub edi,2  ;edi=>open location
  272.   callp openpack,strg,0  ;for reading only
  273.   cmp eax,ERROR
  274.   jnz @f
  275. bad:
  276.   popad
  277.   mov eax,ERROR
  278.   ret
  279. @@:
  280.   stosw   ;save handle
  281.   mov h,ax
  282. ;now to read in the files
  283.   callp readpack,ax,offset temp4,4
  284.   .if eax!=4
  285.     callp closepack,h
  286.     jmp bad
  287.   .endif
  288.   mov ebx,offset temp4
  289.   cmp dword ptr[ebx],01a484150h ;'PAH',26  ;note: it's PAH for Pack files without headers
  290.   .if !zero?
  291.     callp closepack,h
  292.     jmp bad
  293.   .endif
  294.   xor eax,eax
  295.   mov ebx,hdr
  296.   mov ax,[ebx]
  297.   mov wptr[noff],ax
  298.   mov eax,hdr
  299.   add eax,2  ;skip # of files
  300.   callp open_pack,eax,h
  301.   .if eax
  302.     popad
  303.     mov eax,ERROR
  304.     ret
  305.   .endif
  306.   popad
  307.   xor eax,eax
  308.   mov ax,h
  309.   ret
  310. pack_open_hdr endp
  311.  
  312. align 4
  313. pack_close proc,h:word
  314.   pushad
  315.   mov ax,h
  316.   mov esi,pt
  317.   mov ecx,pts
  318. @@:
  319.   cmp [esi].ps.fh,ax
  320.   .if zero?
  321.     mov bptr[esi],0  ;erase filename (empty it)
  322.   .endif
  323.   add esi,sizeof ps
  324.   dec ecx
  325.   jnz @b
  326.   callp closepack,ax
  327.   mov edi,ph
  328.   mov ecx,phs
  329.   mov ax,h
  330.   repnz scasw
  331.   .if zero?
  332.     mov wptr[edi-2],0
  333.     popad
  334.     xor eax,eax
  335.     ret
  336.   .endif
  337.   popad
  338.   mov eax,ERROR
  339.   ret
  340. pack_close endp
  341.  
  342. align 4
  343. int_21h:
  344.   push ds
  345.   mov ds,cs:seldata
  346.   cmp pack_on,0
  347.   jz do_dos
  348.   cmp ah,3dh
  349.   jz _open
  350.   cmp ah,3eh
  351.   jz _close
  352.   cmp ah,3fh
  353.   jz _read
  354.   cmp ah,42h
  355.   jz _lseek
  356. do_dos:
  357.   pop ds
  358.   jmp cs:[old_int21h]
  359.  
  360. _open:
  361. ;search in tables
  362.   cmp chand,0
  363.   jnz do_dos  ;other handle already open!
  364.   pushad
  365.   push es
  366.   mov es,cs:seldata
  367.   mov esi,edx ;strg
  368.   mov edi,offset fn
  369.   xor ecx,ecx
  370.   cld
  371. @@:           ;capatalize the string
  372.   lodsb
  373.   cmp al,0
  374.   jz @f
  375.   cmp al,'\'
  376.   jz notfound
  377.   cmp al,':'
  378.   jz notfound
  379.   .if ((al>='a')&&(al<='z'))
  380.     sub al,32
  381.   .endif
  382.   stosb
  383.   inc ecx
  384.   .if ecx>12
  385.     jmp notfound
  386.   .endif
  387.   jmp @b
  388. @@:
  389.   .if bptr[edi-1]=='.'
  390.     mov bptr[edi-1],0
  391.   .else
  392.     xor al,al
  393.     stosb
  394.   .endif
  395.   mov ebx,pt
  396.   mov ecx,pts
  397.   mov eax,sizeof ps
  398.   mul ecx
  399.   mov edx,offset fn
  400.   add ebx,eax
  401.   sub ebx,sizeof ps  ;ptrs to last entry (so last occurance of file be used instead)
  402. @@:
  403.   cmp bptr[ebx],0
  404.   .if !zero?
  405.     callp strcmp,edx,ebx
  406.     cmp al,0
  407.     jz found
  408.   .endif
  409.   sub ebx,sizeof ps      ;search thru list backwards!!!
  410.   dec ecx
  411.   jnz @b
  412. notfound:
  413.   pop es
  414.   popad
  415.   jmp do_dos
  416. found:
  417. ;pack file found!
  418.   mov ax,[ebx].ps.fh   ;handle
  419.   mov edx,[ebx].ps.off ;offset
  420.   mov ecx,[ebx].ps.siz ;size
  421.   mov coff,edx
  422.   mov cend,edx
  423.   mov chand,ax
  424.   mov cpos,0
  425.   mov csiz,ecx
  426.   add cend,ecx
  427.   mov ecx,edx
  428.   shr ecx,16  ;CX:DX
  429.   mov bx,ax
  430.   mov ax,4200h
  431.   ; callp lseek,ax,ecx,SEEK_SET
  432.   ;can't use this here, LSEEK will override and cause relative seek
  433.   pushfd
  434.   call [old_int21h]
  435.   .if carry?
  436.     ;error
  437.     pop es
  438.     popad
  439.     pop ds
  440.     or byte ptr[esp+8],1      ;set carry on error
  441.     ; flags , cs , eip
  442.     iretd
  443.   .endif
  444.   ;successful
  445.   pop es
  446.   popad
  447.   pop ds
  448.   and byte ptr[esp+8],0feh  ;clear carry
  449.   ; flags , cs , eip
  450.   mov ax,cs:chand
  451.   iretd
  452.  
  453. _close:
  454.   ;bx=hand
  455.   pushad
  456.   mov ax,bx
  457.   mov esi,ph   ;handlers in use
  458.   mov ecx,phs
  459. @@:
  460.   cmp [esi],ax
  461.   jz @f
  462.   add esi,2
  463.   dec ecx
  464.   jnz @b
  465.   popad
  466.   jmp do_dos
  467. @@:
  468.   popad
  469.   mov chand,0      ;Forget about this thing  ßeta V0.03
  470.   pop ds
  471.   and byte ptr[esp+8],0feh  ;clear carry
  472.   ; ret,cs,flags
  473.   iretd
  474.  
  475. _read:
  476.   ;bx=hand
  477.   pushad
  478.   mov ax,bx
  479.   mov esi,ph   ;handlers in use
  480.   mov edx,phs
  481. @@:
  482.   cmp [esi],ax
  483.   jz @f
  484.   add esi,2
  485.   dec edx
  486.   jnz @b
  487.   popad
  488.   jmp do_dos
  489. @@:
  490.   ;reading with a pack file!!
  491.   ;must make sure we don't read past EOF
  492.   ;ecx=MAX TO READ
  493.   mov eax,ecx
  494.   add eax,cpos
  495.   .if eax>csiz
  496.     mov ecx,csiz
  497.     sub ecx,cpos  ;read what is left over  (=0 if cpos=csiz)
  498.   .endif
  499.   mov [esp+6*4],ecx  ;save into ecx
  500.   popad
  501.   pushfd
  502.   call [old_int21h]
  503.   ;gotta fix cpos to ptr to proper location within file
  504.   .if carry?
  505.     or byte ptr[esp+12],1      ;set carry
  506.   .else
  507.     and byte ptr[esp+12],0feh  ;clear carry
  508.     add cpos,eax
  509.   .endif
  510.   pop ds
  511.   iretd
  512.  
  513. _lseek:
  514.   ;bx=hand
  515.   pushad
  516.   mov ax,bx
  517.   mov esi,ph   ;handlers in use
  518.   mov ecx,phs
  519. @@:
  520.   cmp [esi],ax
  521.   jz @f
  522.   add esi,2
  523.   dec ecx
  524.   jnz @b
  525.   popad
  526.   jmp do_dos
  527. @@:
  528.   popad
  529.   ;LSEEKing with a pack file!!
  530.   ;convert CX:DX => EDX
  531.   shl ecx,16
  532.   mov cx,dx
  533.   mov edx,ecx
  534.   .if al==0
  535.     add edx,coff
  536.   .endif
  537.   .if al==1    ;FIX : v2.01 : greatly updated
  538.     .if edx & 80000000h  ;neg?
  539.       add edx,cpos
  540.       add edx,coff
  541.       .if edx > cend || edx < coff
  542.         mov edx,coff
  543.       .endif
  544.     .else
  545.       add edx,cpos
  546.       add edx,coff
  547.       .if edx > cend || edx < coff
  548.         mov edx,cend
  549.       .endif
  550.     .endif
  551.     xor al,al
  552.   .endif
  553.   .if al==2  ;this is not allowed if edx>0 so I just ignore edx!!
  554.     add edx,cend
  555.     .if edx>cend || edx < coff
  556.       mov edx,cend
  557.     .endif
  558.     xor al,al
  559.   .endif
  560.   .if al>2  ;???
  561.     jmp badseek
  562.   .endif
  563.   mov ecx,edx
  564.   shr ecx,16   ;CX:DX
  565.   pushfd
  566.   call [old_int21h]   ;DX:AX
  567.   ;gotta fix eax to ptr to proper location within file
  568.   .if carry?
  569.     ;ds,ret,cs,flg
  570. badseek:
  571.     or byte ptr[esp+12],1      ;set carry
  572.   .else
  573.     ; DX:AX -> EAX
  574.     shl edx,16
  575.     mov dx,ax
  576.     mov eax,edx
  577.     and byte ptr[esp+12],0feh  ;clear carry
  578.     sub eax,coff
  579.     mov cpos,eax   ;new pos
  580.     ; EAX -> DX:AX
  581.     mov edx,eax
  582.     shr edx,16
  583.   .endif
  584.   pop ds
  585.   iretd
  586.  
  587. ;in:
  588. ;ah=45h
  589. ;bx=handle
  590. ;out:
  591. ;ax=new handle
  592. ; NOTE: changing offset of one changes the other.
  593.  
  594.